package com.open.capacity.workflow.controller;


import com.open.capacity.annotation.log.LogAnnotation;
import com.open.capacity.commons.CodeEnum;
import com.open.capacity.commons.Result;
import com.open.capacity.model.system.LoginAppUser;
import com.open.capacity.model.system.SysUser;
import com.open.capacity.user.service.SysUserService;
import com.open.capacity.utils.SysUserUtil;
import com.open.capacity.vo.SysUserRelationExtVo;
import com.open.capacity.workflow.model.WFEngine.WFAuditor;
import com.open.capacity.workflow.model.WFEngine.WFAuditorModel;
import com.open.capacity.workflow.model.WFEngine.WFContent;
import com.open.capacity.workflow.service.WFEngineService;
import com.open.capacity.workflow.vo.WFParameter;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * @author 作者 ftquan 464725602@qq.com
 * @version 创建时间：2017年11月12日 上午22:57:51
 * 流程引擎（流程接口）
 */
@RestController
@Api(tags = "流程引擎模块api")
public class WFEngineController {

    @Autowired
    private SysUserService userService;

    @Autowired
    private WFEngineService engineService;


    /**
     * 初始化流程模板->获取开始节点数据
     *
     * @param isNew      是否是新发起的实例
     * @param processId  流程实例ID
     * @param schemeCode 流程模板编码
     * @return
     */
    @PreAuthorize("hasAuthority('wfendine:get/wfengines/bootstraper')")
    @ApiOperation(value = "初始化流程模板")
    @GetMapping("/wfengines/bootstraper")
    @LogAnnotation(name = "流程", module = "workflow-center", recordRequestParam = false)
    public Result bootstraper(Boolean isNew, String processId, String schemeCode) {
        WFParameter parameter = new WFParameter();
        LoginAppUser loginUser = SysUserUtil.getLoginAppUser();

        parameter.setCompanyId(loginUser.getCompanyId());
        parameter.setDepartmentId(loginUser.getDepartmentId());
        parameter.setUserId(loginUser.getId());
        parameter.setUserName(loginUser.getRealName());
        parameter.setIsNew(isNew);
        parameter.setProcessId(processId);
        parameter.setSchemeCode(schemeCode);

        Result<WFContent> res = engineService.bootstraper(parameter);
        return res;
    }


    /**
     * 流程任务信息
     *
     * @param processId 流程实例ID
     * @param taskId    流程任务id
     * @return
     */
    @PreAuthorize("hasAuthority('wfendine:get/wfengines/taskInfo')")
    @ApiOperation(value = "流程任务信息")
    @GetMapping("/wfengines/taskInfo")
    @LogAnnotation(name = "流程", module = "workflow-center", recordRequestParam = false)
    public Result taskInfo(String processId, String taskId) {
        WFParameter parameter = new WFParameter();
        LoginAppUser loginUser = SysUserUtil.getLoginAppUser();

        parameter.setCompanyId(loginUser.getCompanyId());
        parameter.setDepartmentId(loginUser.getDepartmentId());
        parameter.setUserId(loginUser.getId());
        parameter.setUserName(loginUser.getRealName());
        parameter.setProcessId(processId);
        parameter.setTaskId(taskId);
        parameter.setIsNew(false);

        Result<WFContent> res = engineService.getTaskInfo(parameter);
        return res;
    }


    /**
     * 流程实例信息
     *
     * @param processId 流程实例ID
     * @param taskId    流程任务id
     * @return
     */
    @PreAuthorize("hasAuthority('wfendine:get/wfengines/processInfo')")
    @ApiOperation(value = "流程实例信息")
    @GetMapping("/wfengines/processInfo")
    @LogAnnotation(name = "流程", module = "workflow-center", recordRequestParam = false)
    public Result processInfo(String processId, String taskId) {
        WFParameter parameter = new WFParameter();
        LoginAppUser loginUser = SysUserUtil.getLoginAppUser();

        parameter.setCompanyId(loginUser.getCompanyId());
        parameter.setDepartmentId(loginUser.getDepartmentId());
        parameter.setUserId(loginUser.getId());
        parameter.setUserName(loginUser.getRealName());
        parameter.setProcessId(processId);
        parameter.setTaskId(taskId);
        parameter.setIsNew(false);

        Result<WFContent> res = engineService.getProcessInfo(parameter);
        return res;
    }


    /**
     * 流程实例信息(流程监控)
     *
     * @param processId 流程实例ID
     * @param taskId    流程任务id
     * @return
     */
    @PreAuthorize("hasAuthority('wfendine:get/wfengines/processInfoByMonitor')")
    @ApiOperation(value = "流程实例信息(流程监控)")
    @GetMapping("/wfengines/processInfoByMonitor")
    @LogAnnotation(name = "流程", module = "workflow-center", recordRequestParam = false)
    public Result processInfoMonitor(String processId, String taskId) {
        WFParameter parameter = new WFParameter();
        LoginAppUser loginUser = SysUserUtil.getLoginAppUser();

        parameter.setCompanyId(loginUser.getCompanyId());
        parameter.setDepartmentId(loginUser.getDepartmentId());
        parameter.setUserId(loginUser.getId());
        parameter.setUserName(loginUser.getRealName());
        parameter.setProcessId(processId);
        parameter.setTaskId(taskId);
        parameter.setIsNew(false);

        Result<WFContent> res = engineService.getProcessInfoByMonitor(parameter);
        return res;
    }


    /**
     * 获取下一个节点审核人员
     *
     * @param isNew      是否新发起
     * @param processId  流程实例ID
     * @param taskId     流程任务id
     * @param schemeCode 流程模板编号
     * @param formData   表单信息
     * @return
     */
    @PreAuthorize("hasAuthority('wfendine:get/wfengines/auditor')")
    @ApiOperation(value = "获取下一个节点审核人员")
    @PostMapping("/wfengines/auditor")
    @LogAnnotation(name = "流程", module = "workflow-center", recordRequestParam = false)
    public Result auditor(Boolean isNew, String processId, String schemeCode, String taskId, String formData) {
        WFParameter parameter = new WFParameter();
        LoginAppUser loginUser = SysUserUtil.getLoginAppUser();

        parameter.setCompanyId(loginUser.getCompanyId());
        parameter.setDepartmentId(loginUser.getDepartmentId());
        parameter.setIsNew(isNew);
        parameter.setUserId(loginUser.getId());
        parameter.setUserName(loginUser.getRealName());
        parameter.setProcessId(processId);
        parameter.setSchemeCode(schemeCode);
        parameter.setTaskId(taskId);
        parameter.setFormData(formData);

        Result<List<WFAuditorModel>> res = engineService.getAuditer(parameter);
        if (res.getResp_code().equals(CodeEnum.SUCCESS.getCode())) {
            List<WFAuditorModel> nodelist = new ArrayList<>();
            List<WFAuditorModel> list = res.getData();
            for (WFAuditorModel item : list) {
                if (CollectionUtils.isEmpty(item.getAuditors())) {
                    WFAuditorModel point = new WFAuditorModel();
                    point.setAll(true);
                    point.setNodeName(item.getNodeName());
                    point.setNodeId(item.getNodeId());
                    nodelist.add(point);
                } else {
                    List<WFAuditor> userlist = new ArrayList<>();
                    for (WFAuditor auditor : item.getAuditors()) {
                        switch (auditor.getType()) {//获取人员信息1.岗位2.角色3.用户，4.发起人
                            case 1:
                                SysUserRelationExtVo postRelationList = userService.findUserRelationsByObjectId("Post", auditor.getAuditorId());
                                for (SysUser user : postRelationList.getUserInfoList()) {
                                    WFAuditor model = new WFAuditor();
                                    model.setAuditorId(user.getId());
                                    model.setAuditorName(user.getUserName());
                                    userlist.add(model);
                                }
                                break;
                            case 2:
                                SysUserRelationExtVo roleRelationList = userService.findUserRelationsByObjectId("Role", auditor.getAuditorId());
                                for (SysUser user : roleRelationList.getUserInfoList()) {
                                    WFAuditor model = new WFAuditor();
                                    model.setAuditorId(user.getId());
                                    model.setAuditorName(user.getUserName());
                                    userlist.add(model);
                                }
                                break;
                            case 3:
                                userlist.add(auditor);
                                break;
                            case 4: //发起人
                                userlist.add(auditor);
                                break;
                        }
                    }
                    WFAuditorModel model = new WFAuditorModel();
                    model.setNodeId(item.getNodeId());
                    model.setNodeName(item.getNodeName());
                    model.setAuditors(userlist);

                    nodelist.add(model);
                }
            }

            return Result.succeed(nodelist);
        } else {
            return Result.failed("获取数据失败!");
        }
    }

    /**
     * 创建流程实例
     *
     * @param isNew        是否是新发起的实例
     * @param processId    流程实例ID
     * @param schemeCode   流程模板编码
     * @param processName  流程实例名称
     * @param processLevel 流程重要等级
     * @param description  备注说明
     * @param auditors     审核人
     * @param formData     表单数据
     * @return
     */
    @PreAuthorize("hasAuthority('wfendine:get/wfengines/create')")
    @ApiOperation(value = "创建流程实例")
    @PostMapping("/wfengines/create")
    @LogAnnotation(name = "流程", module = "workflow-center", recordRequestParam = false)
    public Result create(Boolean isNew, String processId, String schemeCode, String processName, Integer processLevel, String description, String auditors, String formData) {
        WFParameter parameter = new WFParameter();
        LoginAppUser loginUser = SysUserUtil.getLoginAppUser();

        parameter.setCompanyId(loginUser.getCompanyId());
        parameter.setDepartmentId(loginUser.getDepartmentId());
        parameter.setUserId(loginUser.getId());
        parameter.setUserName(loginUser.getRealName());
        parameter.setIsNew(isNew);
        parameter.setProcessId(processId);
        parameter.setSchemeCode(schemeCode);
        parameter.setProcessName(processName);
        parameter.setProcessLevel(processLevel);
        parameter.setAuditors(auditors);
        parameter.setFormData(formData);
        parameter.setDescription(description);

        Result<WFContent> res = engineService.create(parameter);
        return res;
    }


    /**
     * 审核流程实例
     *
     * @param taskId      流程任务ID
     * @param verifyType
     * @param description 备注说明
     * @param auditorId   加签人员Id
     * @param description 备注说明
     * @param auditors    审核人
     * @param formData    表单数据
     * @return
     */
    @PreAuthorize("hasAuthority('wfendine:get/wfengines/audit')")
    @ApiOperation(value = "审核流程实例")
    @PostMapping("/wfengines/audit")
    @LogAnnotation(name = "流程", module = "workflow-center", recordRequestParam = false)
    public Result audit(String taskId, String verifyType, String description, String auditorId, String auditorName, String auditors, String formData) {
        WFParameter parameter = new WFParameter();
        LoginAppUser loginUser = SysUserUtil.getLoginAppUser();

        parameter.setCompanyId(loginUser.getCompanyId());
        parameter.setDepartmentId(loginUser.getDepartmentId());
        parameter.setUserId(loginUser.getId());
        parameter.setUserName(loginUser.getRealName());

        parameter.setTaskId(taskId);
        parameter.setVerifyType(verifyType);
        parameter.setAuditorId(auditorId);
        parameter.setAuditorName(auditorName);
        parameter.setAuditors(auditors);
        parameter.setFormData(formData);
        parameter.setDescription(description);
        Result<WFContent> res = engineService.audit(parameter);
        return res;
    }


    /**
     * 撤销审核
     *
     * @param taskId    流程任务ID
     * @param processId 流程id
     * @return
     */
    @PreAuthorize("hasAuthority('wfendine:get/wfengines/revokeAudit')")
    @ApiOperation(value = "撤销审核")
    @PostMapping("/wfengines/revokeAudit")
    @LogAnnotation(name = "流程", module = "workflow-center", recordRequestParam = false)
    public Result revokeAudit(String processId, String taskId) {
        WFParameter parameter = new WFParameter();
        LoginAppUser loginUser = SysUserUtil.getLoginAppUser();

        parameter.setCompanyId(loginUser.getCompanyId());
        parameter.setDepartmentId(loginUser.getDepartmentId());
        parameter.setUserId(loginUser.getId());
        parameter.setUserName(loginUser.getRealName());

        parameter.setTaskId(taskId);
        parameter.setProcessId(processId);
        Result<WFContent> res = engineService.revokeAudit(parameter);
        return res;
    }
}
